import React, { useMemo, Suspense } from 'react';
import { Route, Routes, Link, Navigate, useParams, useLocation } from 'react-router-dom';
import { graphql, useSubscription, usePreloadedQuery, PreloadedQuery } from 'react-relay';
import Box from '@mui/material/Box';
import Tabs from '@mui/material/Tabs';
import Tab from '@mui/material/Tab';
import useQueryLoading from 'src/utils/hooks/useQueryLoading';
import { GraphQLSubscriptionConfig } from 'relay-runtime';
import StixCoreObjectContentRoot from '../../common/stix_core_objects/StixCoreObjectContentRoot';
import StixCoreObjectSimulationResult from '../../common/stix_core_objects/StixCoreObjectSimulationResult';
import Malware from './Malware';
import MalwareKnowledge from './MalwareKnowledge';
import StixDomainObjectHeader from '../../common/stix_domain_objects/StixDomainObjectHeader';
import FileManager from '../../common/files/FileManager';
import MalwarePopover from './MalwarePopover';
import Loader, { LoaderVariant } from '../../../../components/Loader';
import StixCoreObjectHistory from '../../common/stix_core_objects/StixCoreObjectHistory';
import StixCoreObjectOrStixCoreRelationshipContainers from '../../common/containers/StixCoreObjectOrStixCoreRelationshipContainers';
import StixCoreObjectKnowledgeBar from '../../common/stix_core_objects/StixCoreObjectKnowledgeBar';
import ErrorNotFound from '../../../../components/ErrorNotFound';
import { useFormatter } from '../../../../components/i18n';
import Breadcrumbs from '../../../../components/Breadcrumbs';
import { getCurrentTab, getPaddingRight } from '../../../../utils/utils';
import { RootMalwareQuery } from './__generated__/RootMalwareQuery.graphql';
import { RootMalwareSubscription } from './__generated__/RootMalwareSubscription.graphql';
import useHelper from '../../../../utils/hooks/useHelper';
import Security from '../../../../utils/Security';
import { KNOWLEDGE_KNUPDATE } from '../../../../utils/hooks/useGranted';
import MalwareEdition from './MalwareEdition';
import EditEntityControlledDial from '../../../../components/EditEntityControlledDial';

const subscription = graphql`
  subscription RootMalwareSubscription($id: ID!) {
    stixDomainObject(id: $id) {
      ... on Malware {
        ...Malware_malware
        ...MalwareEditionContainer_malware
      }
      ...FileImportViewer_entity
      ...FileExportViewer_entity
      ...FileExternalReferencesViewer_entity
      ...WorkbenchFileViewer_entity
      ...PictureManagementViewer_entity
    }
  }
`;

const malwareQuery = graphql`
  query RootMalwareQuery($id: String!) {
    malware(id: $id) {
      id
      standard_id
      entity_type
      name
      aliases
      x_opencti_graph_data
      stixCoreObjectsDistribution(field: "entity_type", operation: count) {
        label
        value
      }
      ...Malware_malware
      ...MalwareKnowledge_malware
      ...FileImportViewer_entity
      ...FileExportViewer_entity
      ...FileExternalReferencesViewer_entity
      ...WorkbenchFileViewer_entity
      ...PictureManagementViewer_entity
      ...StixCoreObjectContent_stixCoreObject
    }
    connectorsForImport {
      ...FileManager_connectorsImport
    }
    connectorsForExport {
      ...FileManager_connectorsExport
    }
  }
`;

type RootMalwareProps = {
  malwareId: string;
  queryRef: PreloadedQuery<RootMalwareQuery>;
};

const RootMalware = ({ queryRef, malwareId }: RootMalwareProps) => {
  const subConfig = useMemo<GraphQLSubscriptionConfig<RootMalwareSubscription>>(() => ({
    subscription,
    variables: { id: malwareId },
  }), [malwareId]);

  const location = useLocation();
  const { t_i18n } = useFormatter();
  useSubscription<RootMalwareSubscription>(subConfig);
  const { isFeatureEnable } = useHelper();
  const isFABReplaced = isFeatureEnable('FAB_REPLACEMENT');

  const {
    malware,
    connectorsForExport,
    connectorsForImport,
  } = usePreloadedQuery<RootMalwareQuery>(malwareQuery, queryRef);

  const isOverview = location.pathname === `/dashboard/arsenal/malwares/${malwareId}`;
  const paddingRight = getPaddingRight(location.pathname, malwareId, '/dashboard/arsenal/malwares');
  const link = `/dashboard/arsenal/malwares/${malwareId}/knowledge`;
  return (
    <>
      {malware ? (
        <>
          <Routes>
            <Route
              path="/knowledge/*"
              element={
                <StixCoreObjectKnowledgeBar
                  stixCoreObjectLink={link}
                  availableSections={[
                    'victimology',
                    'threats',
                    'threat_actors',
                    'intrusion_sets',
                    'campaigns',
                    'incidents',
                    'variants',
                    'tools',
                    'attack_patterns',
                    'vulnerabilities',
                    'indicators',
                    'observables',
                    'infrastructures',
                    'sightings',
                  ]}
                  stixCoreObjectsDistribution={malware.stixCoreObjectsDistribution}
                />
              }
            />
          </Routes>
          <div style={{ paddingRight }}>
            <Breadcrumbs variant="object" elements={[
              { label: t_i18n('Arsenal') },
              { label: t_i18n('Malwares'), link: '/dashboard/arsenal/malwares' },
              { label: malware.name, current: true },
            ]}
            />
            <StixDomainObjectHeader
              entityType="Malware"
              stixDomainObject={malware}
              PopoverComponent={<MalwarePopover />}
              EditComponent={isFABReplaced && (
                <Security needs={[KNOWLEDGE_KNUPDATE]}>
                  <MalwareEdition
                    malwareId={malware.id}
                    controlledDial={EditEntityControlledDial}
                  />
                </Security>
              )}
              enableQuickSubscription={true}
            />
            <Box
              sx={{
                borderBottom: 1,
                borderColor: 'divider',
                marginBottom: 3,
                display: 'flex',
                justifyContent: 'space-between',
                alignItem: 'center',
              }}
            >
              <Tabs
                value={getCurrentTab(location.pathname, malware.id, '/dashboard/arsenal/malwares')}
              >
                <Tab
                  component={Link}
                  to={`/dashboard/arsenal/malwares/${malware.id}`}
                  value={`/dashboard/arsenal/malwares/${malware.id}`}
                  label={t_i18n('Overview')}
                />
                <Tab
                  component={Link}
                  to={`/dashboard/arsenal/malwares/${malware.id}/knowledge/overview`}
                  value={`/dashboard/arsenal/malwares/${malware.id}/knowledge`}
                  label={t_i18n('Knowledge')}
                />
                <Tab
                  component={Link}
                  to={`/dashboard/arsenal/malwares/${malware.id}/content`}
                  value={`/dashboard/arsenal/malwares/${malware.id}/content`}
                  label={t_i18n('Content')}
                />
                <Tab
                  component={Link}
                  to={`/dashboard/arsenal/malwares/${malware.id}/analyses`}
                  value={`/dashboard/arsenal/malwares/${malware.id}/analyses`}
                  label={t_i18n('Analyses')}
                />
                <Tab
                  component={Link}
                  to={`/dashboard/arsenal/malwares/${malware.id}/files`}
                  value={`/dashboard/arsenal/malwares/${malware.id}/files`}
                  label={t_i18n('Data')}
                />
                <Tab
                  component={Link}
                  to={`/dashboard/arsenal/malwares/${malware.id}/history`}
                  value={`/dashboard/arsenal/malwares/${malware.id}/history`}
                  label={t_i18n('History')}
                />
              </Tabs>
              {isOverview && (
                <StixCoreObjectSimulationResult id={malware.id} type="threat" />
              )}
            </Box>
            <Routes>
              <Route
                path="/"
                element={
                  <Malware malwareData={malware} />
                }
              />
              <Route
                path="/knowledge"
                element={
                  <Navigate
                    replace={true}
                    to={`/dashboard/arsenal/malwares/${malwareId}/knowledge/overview`}
                  />
                }
              />
              <Route
                path="/knowledge/*"
                element={<MalwareKnowledge malware={malware} />}
              />
              <Route
                path="/content/*"
                element={
                  <StixCoreObjectContentRoot
                    stixCoreObject={malware}
                  />
                }
              />
              <Route
                path="/analyses"
                element={
                  <StixCoreObjectOrStixCoreRelationshipContainers
                    stixDomainObjectOrStixCoreRelationship={malware}
                  />
                }
              />
              <Route
                path="/files"
                element={
                  <FileManager
                    id={malwareId}
                    connectorsImport={connectorsForImport}
                    connectorsExport={connectorsForExport}
                    entity={malware}
                  />
                }
              />
              <Route
                path="/history"
                element={
                  <StixCoreObjectHistory
                    stixCoreObjectId={malwareId}
                  />
                }
              />
            </Routes>
          </div>
        </>
      ) : (
        <ErrorNotFound />
      )}
    </>
  );
};

const Root = () => {
  const { malwareId } = useParams() as { malwareId: string; };
  const queryRef = useQueryLoading<RootMalwareQuery>(malwareQuery, {
    id: malwareId,
  });

  return (
    <>
      {queryRef && (
        <Suspense fallback={<Loader variant={LoaderVariant.container} />}>
          <RootMalware queryRef={queryRef} malwareId={malwareId} />
        </Suspense>
      )}
    </>
  );
};

export default Root;
